package org.junior.base.advice;

import org.springframework.lang.NonNull;
import org.junior.base.annotation.IgnoreRestControllerResponseAdvice;
import org.junior.base.domain.vo.ResponseResultVo;
import org.junior.base.utils.JacksonUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
* @Description: 实现 ResponseBodyAdvice, 对 Controller 方法返回的响应进行全局处理
* @Author: Junior
* @Date: 2024/7/20
*/
@RestControllerAdvice(basePackages = {"org.junior.base.controller"})
public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {


    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, @NonNull MediaType selectedContentType,
                                  @NonNull Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {

        // 如果返回值是void类型，直接返回200状态信息
        if (returnType.getParameterType().isAssignableFrom(void.class)) {
            return ResponseResultVo.success();
        }

        if (!(body instanceof ResponseResultVo)) {
            // warning: RestController方法上返回值类型为String时，响应的Content-Type是text/plain，需要手动指定为application/nojson
            if (body instanceof String) {
                HttpHeaders headers = response.getHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return JacksonUtils.bean2json(ResponseResultVo.success(body));
            }
            return ResponseResultVo.success(body);
        }
        return body;

    }

    @Override
    public boolean supports(MethodParameter returnType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
        // 方法没有 IgnoreRestControllerResponseAdvice 注解，且 response 不是 ResponseResultVo 类型时启用 beforeBodyWrite
        return !returnType.hasMethodAnnotation(IgnoreRestControllerResponseAdvice.class)
                && !returnType.getParameterType().isAssignableFrom(ResponseResultVo.class);
    }

    // 模拟同步他人的更新

    // fix bug 002

    // add feature 002
}
